﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using ORMAC.Core;
using System.Xml;
using System.Linq.Expressions;

namespace ORMAC
{
    public class OReader:IReader
    {
        #region Private Members
        private string connectionString;
        /// <summary>
        /// keeps a list of context members for each object type
        /// </summary>
        private ContextMemberCollection context=new ContextMemberCollection();
        #endregion
        #region IORMAC Members


        public List<T> LoadFromDataSet<T>(System.Data.DataSet dataSet)
            where T : new()
        {
            throw new NotImplementedException();
        }

        public List<T> LoadFromXml<T>(string xmlPathName, string schemalName = null)
            where T : new()

        {
            XmlLoader loader = new XmlLoader();
            return loader.GetList<T>(xmlPathName);
        }
        public List<T> LoadFromXmlDocument<T>(XmlDocument doc, string schemalName = null)
            where T : new()
        {
            XmlLoader loader = new XmlLoader();
            return loader.GetList<T>(doc);
        }

        #endregion

        #region IORMAC Members

        public List<T> LoadFromDatabase<T>()
            where T : new()
            
        {
            DatabaseLoader loader=new DatabaseLoader(context);
            DataSet set=loader.PrefetchDataFromDB<T>(this.connectionString,string.Empty);
            loader.dataSet = set;
            return loader.GetList<T>(set, string.Empty);
        }

        #endregion

        #region IORMAC Members

        public void SetConnectionString(string connectionString = null)
        {
            this.connectionString = connectionString;
        }

        #endregion


        public List<T> LoadFromDatabase<T>(Expression<Func<T, bool>> query) where T : new()
        {
            DatabaseLoader loader = new DatabaseLoader(context);
            DataSet set = loader.PrefetchDataFromDB<T>(this.connectionString, string.Empty, query);
            loader.dataSet = set;
            return loader.GetList<T>(set, string.Empty);
        }
        public List<T> LoadFromDatabase<T>(string query) where T : new()
        {
            DatabaseLoader loader = new DatabaseLoader(context);
            DataSet set = loader.PrefetchDataFromDB<T>(this.connectionString, string.Empty, query);
            loader.dataSet = set;
            return loader.GetList<T>(set, string.Empty);
        }

        /// <summary>
        /// Runs a stored procedure
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="repository"></param>
        /// <param name="methodName"></param>
        /// <param name="paramList"></param>
        /// <returns></returns>
        public List<T> Exceute<T>(object repository,string methodName, params object[] paramList) where T : new()
        {
            DatabaseLoader loader = new DatabaseLoader(context);
            DataSet set = loader.Exceute<T>(this.connectionString, repository, methodName, paramList);
            loader.dataSet = set;
            var res=loader.GetList<T>(set,string.Empty,true);
            return res;
        }

        public T ExceuteScalar<T>(object repository, string methodName, params object[] paramList) 
        {
            DatabaseLoader loader = new DatabaseLoader(context);
            T res = loader.ExceuteScalar<T>(this.connectionString, repository, methodName, paramList);
            return res;
        }




        public IReader LoadObject<T>(Expression<Func<T, object>> member)
        {
            DatabaseLoader loader = new DatabaseLoader(context);
            loader.AddMemberToContext<T>(member);
            return this;
        }
    }
}
